#include <iostream>
#include <string>

#include "user.pb.h"
#include "mprpcapplication.h"
#include "rpcprovider.h"

/*
 * 本地服务，里面有两个方法Login和GetFriendLists
 */
class UserService : public fixbug::UserServiceRpc { // 利用继承在rpc服务发布端发布远程调用方法
public:
    // 本地方法
    bool Login(std::string name, std::string pwd) {
        std::cout << "doing local service: Login" << std::endl;
        std::cout << "name:" << name << " pwd:" << pwd << std::endl;
        return true;
    }

    bool Register(uint32_t id, std::string name, std::string pwd) {
        std::cout << "doing local service: Register" << std::endl;
        std::cout << "id:" << id << " name:" << name << " pwd:" << pwd << std::endl;
        return true;
    }

    /*
     * 重写基类的虚函数，框架直接调用
     * 1. caller ==> 提出Login(LoginRequest) ==> muduo网络传输 ==> callee 
     * 2. callee ==> 收到Login(LoginRequest) ==> 完成重写的Login方法 ==> 发回caller 
     */
    void Login(::google::protobuf::RpcController* controller,
                const ::fixbug::LoginRequest* request,
                ::fixbug::LoginResponse* response,
                ::google::protobuf::Closure* done) {
        // 开始业务，通过序列化的请求提取出数据
        std::string name = request->name();            
        std::string pwd = request->pwd();
        
        bool login_res = Login(name, pwd);  // 服务器本地方法

        // 响应写入
        fixbug::ResultCode* code = response->mutable_result();
        code->set_errcode(0);
        code->set_errmsg("");
        response->set_success(login_res);

        // 执行回调函数
        done->Run();
    }

    void Register(::google::protobuf::RpcController* controller,
                    const ::fixbug::RegisterRequest* request,
                    ::fixbug::RegisterResponse* response,
                    ::google::protobuf::Closure* done) {
        uint32_t id = request->id();
        std::string name = request->name();            
        std::string pwd = request->pwd();

        bool register_res = Register(id, name, pwd);  // 服务器本地方法

        fixbug::ResultCode* code = response->mutable_result();
        code->set_errcode(0);
        code->set_errmsg("");
        response->set_success(register_res);

        done->Run();
    }
};

int main(int argc, char* argv[]) {
    // 本地使用
    // UserService us;
    // us.Login("zhang san", "123456");

    // 远程调用 框架初始化 provider -i config.conf
    MprpcApplication::Init(argc, argv);

    // 发布服务到rpc节点上
    RpcProvider provider;
    provider.NotifyService(new UserService());

    // 启动rpc节点，进程进入阻塞状态，等待远程rpc调用
    provider.Run();

    return 0;
}